#ifndef AC67D2A6_CCBC_4DAA_A26D_F08CF622B21E
#define AC67D2A6_CCBC_4DAA_A26D_F08CF622B21E

#include"nocopy.hpp"
#include"Log.hpp"
#include<cstring>
#include<sys/epoll.h>

class Epoller : public nocopy
{
    static const int size = 128;

public:
    Epoller()
    {
        //创建epoll模型
        epfd_ = epoll_create(size);
        if (epfd_ == -1)
        {
            lg(Error, "epoll_create error : %s", strerror(errno));
        }
        else
        {
            lg(Info, "epoll_create success: %d", epfd_);
        }
    }
    
    ~Epoller()
    {
        if (epfd_ >= 0) 
        {
            close(epfd_);
        }
    }


    //epoll_wait等待函数， 第一个参数就是将就绪的节点拿出去， 第二个参数就是最多拿几个。
    int EpollerWait(struct epoll_event revents[], int num)    
    {
        int n = epoll_wait(epfd_, revents, num, timeout_);
        return n;
    }

    int EpollerUpdate(int oper, int sock, uint32_t event)
    {
        int n = 0;

        if(oper == EPOLL_CTL_DEL)
        {   
            n = epoll_ctl(epfd_, oper, sock, nullptr);  //将事件设置为nullptr， 就是删除事件了。

            if (n != 0)
            {
                lg(Error, "delete epoll_ctl delete error!");
            }
        }
        else
        {
            //在用户曾定义对某个文件fd关心的那个事件。
            struct epoll_event ev;   
            ev.events = event;
            ev.data.fd = sock;     //方便后期得知是哪一个文件fd就绪了。

            n = epoll_ctl(epfd_, oper, sock, &ev);   //将事件设置进入内核
            if (n != 0)
            {
                lg(Error, "epoll_ctl error!");
            }
        }   

        return n;
    }


private:
    int epfd_;

    int timeout_{3000};


};










#endif /* AC67D2A6_CCBC_4DAA_A26D_F08CF622B21E */
